package net.youpoint.core.beans;

import java.util.List;
import java.util.Map.Entry;

public class GChartData {

	private int picWidth; // width of diagram
	private int picHeight; // height of diagram

	private boolean hasLegend; // make a legend to diagram or not

	private final boolean hasTitle;
	private int titleLineLength; // length of legend string line (split on few
									// lines)
	private String title;

	private List<Entry<String, Integer>> items;

	public GChartData() {
		this.picWidth = 500;
		this.picHeight = 300;

		this.hasLegend = true;

		this.hasTitle = false;
		this.titleLineLength = 20;
		this.title = "empty";
	}

	/**
	 * get url like
	 * http://chart.apis.google.com/chart?cht=p3&chs=250x100&chd=t:60
	 * ,40&chl=Hello|World of question diagram to build it by google chart api
	 * 
	 * @return url to retreive diagram
	 */
	public String getChartUrl() {
		String res = null;

		String strData = "";
		String strLegend = "";

		for (final Entry<String, Integer> tmp : this.items) {
			strData += ecapeUrlParam(String.valueOf(tmp.getValue())) + ",";
			strLegend += ecapeUrlParam(tmp.getKey()
			// + " (" + tmp.getValue() + ")"
					)
					+ "|";
		}
		strData = strData.substring(0, strData.length() - 1);
		strLegend = strLegend.substring(0, strLegend.length() - 1);

		String titleParam = "";
		if (this.hasTitle) {
			String strTitle = this.title;

			while (strTitle.length() > 0) {
				final String tmp = cutString(strTitle, this.titleLineLength);

				final int cutLen = tmp.length();

				strTitle = strTitle.substring(cutLen);

				titleParam += ecapeUrlParam(tmp) + "|";
			}

			titleParam = titleParam.substring(0, titleParam.length() - 1);

			titleParam = "&chtt=" + titleParam;
		}

		String legendParam = "";
		if (this.hasLegend) {
			legendParam = "&chdl=" + strLegend + "&chdlp=bv";
			// legendParam = "&chl=" + strLegend;
		}

		res = "http://chart.apis.google.com/chart?cht=p3" + "&chco=66CC33"
				+ "&chd=t:"
				+ strData
				+
				// URL.encode("&chl=30%|25%|50%") +
				legendParam + titleParam + "&chs="
				+ String.valueOf(this.picWidth) + "x"
				+ String.valueOf(this.picHeight);

		return res;
	}

	/**
	 * escape special characters of string
	 * 
	 * @param src
	 *            string need to be escaped
	 * 
	 * @return escaped string
	 */
	private static String ecapeUrlParam(final String src) {
		String res = "";

		res = src;

		final String[] sa = new String[] { "'", "|", ",", "(", ")", "-", "_",
				".", "!", "~", "*", ";", "/", "?", ":", "&", "=", "+", "$", "#" };

		for (final String ch : sa) {
			final int codePoint = String.valueOf(ch).codePointAt(0);
			final String chex = "%" + Integer.toHexString(codePoint);

			res = res.replace(ch, chex);
		}

		return res;
	}

	/**
	 * cut string to maxLength length
	 * 
	 * @param src
	 *            cutted string
	 * @param maxLength
	 *            to what length no cut
	 * 
	 * @return resulting string
	 */
	private String cutString(final String src, final int maxLength) {
		String res = "";

		if (src != null) {

			if (maxLength > src.length()) {

				res = src.substring(0, src.length());
			} else {

				res = src.substring(0, maxLength);

				final int spacePos = res.lastIndexOf(" ");
				if (spacePos != -1) {
					res = src.substring(0, spacePos);
				}
			}
		}

		return res;
	}

	public boolean isHasLegend() {
		return this.hasLegend;
	}

	public void setHasLegend(final boolean hasLegend) {
		this.hasLegend = hasLegend;
	}

	public int getTitleLineLength() {
		return this.titleLineLength;
	}

	public void setTitleLineLength(final int titleLineLength) {
		this.titleLineLength = titleLineLength;
	}

	public int getPicWidth() {
		return this.picWidth;
	}

	public void setPicWidth(final int picWidth) {
		this.picWidth = picWidth;
	}

	public int getPicHeight() {
		return this.picHeight;
	}

	public void setPicHeight(final int picHeight) {
		this.picHeight = picHeight;
	}

	public String getTitle() {
		return this.title;
	}

	public void setTitle(final String title) {
		this.title = title;
	}

	public List<Entry<String, Integer>> getItems() {
		return this.items;
	}

	public void setItems(final List<Entry<String, Integer>> items) {
		this.items = items;
	}

}
